package com.bw.android.bwgao6week2a;

import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;

import androidx.lifecycle.ViewModelProvider;

import com.bw.android.bwgao6week2a.databinding.ActivityLiveBinding;
import com.bw.android.bwgao6week2a.vm.LiveViewModel;
import com.bw.android.network.RequestClient;
import com.bw.android.network.bean.OpenLiveBean;
import com.bw.ch.baselib.BaseBindingActivity;
import com.kd.easybarrage.Barrage;
import com.ksyun.media.streamer.capture.CameraCapture;
import com.ksyun.media.streamer.kit.KSYStreamer;
import com.ksyun.media.streamer.kit.StreamerConstants;
import io.reactivex.schedulers.Schedulers;

/**
 * 金山云直播SDK
 * <a href="https://gitee.com/ksvc/KSYLive_Android">金山云直播SDK</a>
 * <a href="https://gitee.com/fei1024/KSYStreamer_Android">金山云直播推流</a>
 */
public class LiveActivity extends BaseBindingActivity<ActivityLiveBinding> {
    private OpenLiveBean.LiveDataBean mLiveDataBean;
    private LiveViewModel mLiveViewModel;
    public static void open(Context context, OpenLiveBean.LiveDataBean liveBean) {
        Intent intent = new Intent(context, LiveActivity.class);
        intent.putExtra("data", liveBean);
        context.startActivity(intent);
    }
    private KSYStreamer mStreamer;

    @Override
    protected void onResume() {
        super.onResume();
        // 一般可以在onResume中开启摄像头预览
        mStreamer.startCameraPreview();
        // 调用KSYStreamer的onResume接口
        mStreamer.onResume();
        // 如果onPause中切到了DummyAudio模块，可以在此恢复
        mStreamer.setUseDummyAudioCapture(false);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mStreamer.onPause();
        // 一般在这里停止摄像头采集
        mStreamer.stopCameraPreview();
        // 如果希望App切后台后，停止录制主播端的声音，可以在此切换为DummyAudio采集，
        // 该模块会代替mic采集模块产生静音数据，同时释放占用的mic资源
        mStreamer.setUseDummyAudioCapture(true);
    }

    @Override
    public int getLayout() {
        return R.layout.activity_live;
    }

    @Override
    protected void initView() {
        // 创建KSYStreamer实例
        mStreamer = new KSYStreamer(this);
        // 设置预览View
        mStreamer.setDisplayPreview(mBinding.cameraPreview);
        // 设置推流url（需要向相关人员申请，测试地址并不稳定！）
//        mStreamer.setUrl("rtmp://mobile.kscvbu.cn/live/{streamName}");
        // 设置预览分辨率, 当一边为0时，SDK会根据另一边及实际预览View的尺寸进行计算
        mStreamer.setPreviewResolution(480, 0);
        // 设置推流分辨率，可以不同于预览分辨率（不应大于预览分辨率，否则推流会有画质损失）
        mStreamer.setTargetResolution(480, 0);
        // 设置预览帧率
        mStreamer.setPreviewFps(15);
        // 设置推流帧率，当预览帧率大于推流帧率时，编码模块会自动丢帧以适应设定的推流帧率
        mStreamer.setTargetFps(15);
        // 设置视频码率，分别为初始平均码率、最高平均码率、最低平均码率，单位为kbps，另有setVideoBitrate接口，单位为bps
        mStreamer.setVideoKBitrate(600, 800, 400);
        // 设置音频采样率
        mStreamer.setAudioSampleRate(44100);
        // 设置音频码率，单位为kbps，另有setAudioBitrate接口，单位为bps
        mStreamer.setAudioKBitrate(48);
        /**
         * 设置编码模式(软编、硬编)，请根据白名单和系统版本来设置软硬编模式，不要全部设成软编或者硬编,白名单可以联系金山云商务:
         * StreamerConstants.ENCODE_METHOD_SOFTWARE
         * StreamerConstants.ENCODE_METHOD_HARDWARE
         */
        mStreamer.setEncodeMethod(StreamerConstants.ENCODE_METHOD_SOFTWARE);
        // 设置屏幕的旋转角度，支持 0, 90, 180, 270
        mStreamer.setRotateDegrees(0);
        // 设置开始预览使用前置还是后置摄像头
        mStreamer.setCameraFacing(CameraCapture.FACING_BACK);
        // 设置Info回调，可以收到相关通知信息
        mStreamer.setOnInfoListener(new KSYStreamer.OnInfoListener() {
            @Override
            public void onInfo(int what, int msg1, int msg2) {
                // ...
            }
        });
        // 设置错误回调，收到该回调后，一般是发生了严重错误，比如网络断开等，
        // SDK内部会停止推流，APP可以在这里根据回调类型及需求添加重试逻辑。
        mStreamer.setOnErrorListener(new KSYStreamer.OnErrorListener() {
            @Override
            public void onError(int what, int msg1, int msg2) {
                String errMsg = "what="+what + ", msg1="+msg1 + ", msg2="+msg2;
                Log.e(AppInstance.TAG,errMsg);
                Toast.makeText(LiveActivity.this, errMsg, Toast.LENGTH_LONG).show();
            }
        });

        //初始化直播界面的视图模型【LiveViewModel】
        mLiveViewModel = new ViewModelProvider(this).get(LiveViewModel.class);
        mBinding.setLiveModel(mLiveViewModel);
        //点击发送弹幕按钮
        mBinding.btnSendBarrage.setOnClickListener( v -> {
            //发送弹幕
            mBinding.barrageView.addBarrage(new Barrage(mLiveViewModel.barrageStr.getValue()));
        });
    }

    @Override
    protected void initData() {
        mLiveDataBean = (OpenLiveBean.LiveDataBean) getIntent().getSerializableExtra("data");
        Log.d(AppInstance.TAG, "liveId = " + mLiveDataBean.toString());
        //对开播地址中的【pwd】参数加密
        //开播地址格式：rtmp://10.59.9.24:1395/xxx/yyy/zzz?pwd=JaF7w8W/XzNbr2zi+JgF9z3M26AHbNjKDziDO5
        String url = mLiveDataBean.getLiveRtmpUrl();
        /**
         * 示例
         * split[0]=“rtmp://10.59.9.24:1395/xxx/yyy/zzz”;
         * split[1]=“JaF7w8W/XzNbr2zi+JgF9z3M26AHbNjKDziDO5”;
         */
        String[] split = url.split("[?]pwd=");
        String s=null;
        try {
            s= RsaCoder.encryptByPublicKey(RsaCoder.decryptByPublicKey(split[1]));
            s=s.replaceAll("/","-");
            s=s.replaceAll("\\+","~");
            //s = "JaF7w8W-XzNbr2zi~JgF9z3M26AHbNjKDziDO5";
            String aa=split[0] + "?pwd="+s;
            //aa = "rtmp://10.59.9.24:1395/xxx/yyy/zzz?pwd=JaF7w8W-XzNbr2zi~JgF9z3M26AHbNjKDziDO5";
            //设置推流url
            mStreamer.setUrl(aa);
            //开始直播
            mStreamer.startStream();
        }catch (Exception e){
            throw new RuntimeException(e);
        }

    }

    /**
     * 停止播放
     */
    private void stopLive() {
        final int userId = AppInstance.getInstance().getUserId();
        final String sessionId = AppInstance.getInstance().loginResultBean.getSessionId();
        if (userId > 0 && sessionId != null) {
            RequestClient.buildService().closeLive(userId, sessionId)
                    .subscribeOn(Schedulers.io())
                    .observeOn(Schedulers.io())
                    .subscribe(closeLiveBean -> {
                        Log.d(AppInstance.TAG, "关闭直播 status="+closeLiveBean.status);
                    }, throwable -> {
                        Log.e(AppInstance.TAG, throwable.toString());
                    });
        }
    }
    @Override
    protected void onDestroy() {
        // 清理相关资源
        mStreamer.release();
        mBinding.cameraPreview.destroyDrawingCache();
        mBinding.barrageView.destroy();
        stopLive();
        super.onDestroy();
    }
}